<template>
  <div class="app-container">
    <k-button v-if="authorityHandle(165)" class="top-btn" value="添加角色" @click.native="creatCreateRoleDialog" />

    <!--表格相关 -->
    <el-table
      :data="listData"
      fit
      border
      highlight-current-row
      style="width: 100%;border-radius:8px;"
      :header-cell-style="{background:'#F6F5FA',color:'#4E4F62'}"
    >
      <el-table-column width="80px" type="index" label="序号" align="center" />
      <el-table-column prop="roleName" min-width="100px" label="角色名称" align="center" show-overflow-tooltip />
      <el-table-column prop="roleLevel" min-width="100px" label="级别" align="center" show-overflow-tooltip />
      <el-table-column prop="parentName" min-width="100px" label="直属上级角色" align="center" show-overflow-tooltip />
      <el-table-column min-width="150px" label="操作" align="center">
        <template slot-scope="scope">
          <div class="op-div">
            <k-button class="table-btn" value="查看/修改" @click.native="updateRedDialog(scope.row)" />
            <k-button class="table-btn" value="权限配置" @click.native="permissionSetting(scope.row)" />
            <k-button
              v-if="authorityHandle(165)"
              class="table-btn"
              value="删除"
              :disabled="scope.row.openStatus === 1 ? true:false"
              @click.native="deleteRedItem(scope.row)"
            />
          </div>
        </template>
      </el-table-column>
    </el-table>
    <pagination
      v-show="totalRows > 0"
      :total="totalRows"
      :page.sync="listQuery.pager.pageNo"
      :limit.sync="listQuery.pager.pageSize"
      @pagination="loadData"
    />
    <!-- 创建弹窗 -->
    <k-dialog
      :show-hide.sync="creatRoleDialog.showHide"
      :modal-append-to-body="false"
      :append-to-body="true"
      :title="textMap[dialogStatus]"
      class-name="creatRoleDialog_dialog"
      :show-foot="false"
      :two-btn="authorityHandle(165)"
      @click="createRole"
    >
      <div class="dialog_creatRoleDialog">
        <el-form :model="roleInfo" label-width="auto">
          <el-form-item label="角色名称：">
            <el-input
              v-model="roleInfo.roleName"
              :readonly="!authorityHandle(165)"
              show-word-limit
              placeholder="请输入角色名称"
            />
          </el-form-item>

          <el-form-item v-if="dialogStatus === 'update' && userOriginal" label="级别：">
            <el-input v-model="roleInfo.roleLevel" :readonly="!authorityHandle(165)" readonly />
          </el-form-item>

          <el-form-item v-else label="级别：">
            <el-select v-model="roleInfo.roleLevel" :disabled="!authorityHandle(165)" placeholder="请选择">
              <el-option label="1" :value="1" />
              <el-option label="2" :value="2" />
              <el-option label="3" :value="3" />
              <el-option label="4" :value="4" />
              <el-option label="5" :value="5" />
            </el-select>
          </el-form-item>

          <el-form-item v-if="roleInfo.roleLevel !== 1" label="直属上级角色：">
            <el-select v-model="roleInfo.roleParentId" :disabled="!authorityHandle(165)" placeholder="请选择">
              <el-option v-for="item in allRoleData" :key="item.id" :label="item.roleName" :value="item.id" />
            </el-select>
          </el-form-item>
        </el-form>
      </div>
    </k-dialog>

    <!-- 权限创建弹窗 -->
    <k-dialog
      :show-hide.sync="permissionSettingDialog"
      :modal-append-to-body="false"
      :append-to-body="true"
      title="权限配置"
      :show-foot="false"
      :two-btn="authorityHandle(165)"
      @click="savePermissionSetting"
    >
      <div class="dialog_permission">
        <tree-transfer
          :title="['未选权限','已选权限']"
          :from_data="fromData"
          :to_data="toData"
          :default-props="{label:'name',children:'permissionList'}"
          pid="parentId"
          height="540px"
          open-all
          @add-btn="add"
          @remove-btn="remove"
        />
      </div>
    </k-dialog>
  </div>
</template>
<script>
import {
  completePermission,
  saveRoleData,
  upperRoleByLevel,
  listRoleData,
  deleteRoleData,
  updateRoleData,
  permissionIdListByRoleId,
  configPermission,
  permissionByUser
} from '@/api/permission/permission.js'
import treeTransfer from 'el-tree-transfer' // 引入

import Pagination from '@/components/Pagination'

export default {
  components: {
    Pagination,
    treeTransfer
  },
  data() {
    return {
      dialogStatus: 'create',
      textMap: {
        update: '修改角色',
        create: '创建角色'
      },
      totalRows: 0, // 分页组件--数据总条数
      listQuery: {
        pager: {
          pageNo: 1,
          pageSize: 10,
          totalRows: '',
          start: ''
        },
        sort: '', // 排序字段 为对应列名,
        direction: '' // 排序 正向(asc)逆向(desc),
      },
      listData: [],

      // 角色信息
      roleInfo: {
        id: undefined,
        roleName: undefined,
        roleLevel: undefined,
        roleParentId: undefined
      },
      userOriginal: false,
      allRoleData: [], // 所有角色

      creatRoleDialog: {
        showHide: false
      },
      permissionSettingDialog: false,
      role_Id: undefined,
      fromData: [],
      toData: []
    }
  },

  watch: {
    'roleInfo.roleLevel': {
      handler(v) {
        if (v) {
          if (this.dialogStatus == 'create') {
            this.roleInfo.roleParentId = undefined
          }

          if (v === 1) {
            // 最高管理操作
          } else {
            this.getUpperRoleByLevel(v)
          }
        }
      },
      deep: true
    }
  },
  created() {
    this.loadData()
    permissionByUser().then(res => {
    })
  },

  methods: {
    // 请求头前置处理
    requestFront(data) {
      // 去除value为''的key
      if (data.roleLevel === 1) {
        data.roleParentId = undefined
      }
      const really = {}
      const params = Object.keys(data)
      for (let i = 0; i < params.length; i++) {
        if (data[params[i]] !== undefined) {
          really[params[i]] = data[params[i]]
        }
      }
      return really
    },

    loadData() {
      listRoleData(this.listQuery).then(res => {
        this.totalRows = res.data.totalRows
        this.listData = res.data.rows
      })
    },

    // 创建角色
    creatCreateRoleDialog() {
      this.$resetForm(this.roleInfo)
      this.dialogStatus = 'create'
      this.getAllRole()
    },

    // 修改
    updateRedDialog(row) {
      this.dialogStatus = 'update'
      this.getAllRole(row)
    },

    // 获取已添加的所有角色
    getAllRole(row) {
      if (this.dialogStatus == 'update') {
        this.roleInfo = row
        if (row.roleLevel === 1) {
          this.userOriginal = true
        } else {
          this.userOriginal = false
        }
        this.roleInfo.parentName = undefined
      }
      this.creatRoleDialog.showHide = true
    },

    getUpperRoleByLevel(level) {
      const data = { level }
      upperRoleByLevel(data).then(res => {
        this.allRoleData = res.data
      })
    },

    // 保存角色
    createRole() {
      if (this.dialogStatus == 'create') {
        saveRoleData(this.requestFront(this.roleInfo)).then(res => {
          if (res.data.success) {
            this.$message.success('创建成功')
            this.loadData()
            this.creatRoleDialog.showHide = false
          } else {
            this.$message.error(res.data.msg)
          }
        })
      } else {
        updateRoleData(this.requestFront(this.roleInfo)).then(res => {
          if (res.data.success) {
            this.$message.success('修改成功')
            this.loadData()
            this.creatRoleDialog.showHide = false
          } else {
            this.$message.error(res.data.msg)
          }
        })
      }
    },

    // 删除
    deleteRedItem(row) {
      this.$confirm('确定删除么?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteRoleData({
          roleId: row.id
        }).then(res => {
          if (res.data.success) {
            this.$message.success('删除成功')
            this.loadData()
          } else {
            this.$message.success(res.data.msg)
          }
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消'
        })
      })
    },

    // 权限配置
    permissionSetting(row) {
      this.role_Id = row.id
      this.getCompletePermission(row)
    },

    // 角色已获得权限
    getPermissionIdListByRoleId(row, list) {
      permissionIdListByRoleId({
        roleId: row.id
      }).then(res => {
        if (!res.data || res.data.length == 0) { // 无权限直接赋值
          this.fromData = list
          this.toData = []
          this.permissionSettingDialog = true
        } else {
          this.permissionEcho(list, res.data)
        }
      })
    },

    // 权限回显处理(开始)
    permissionEcho(allPower, myPower) {
      const list = this.detection(allPower).concat()
      const sonData = []
      for (let i = 0; i < myPower.length; i++) { // 查找id所对应权限对象
        sonData.push(this.seekAuthority(myPower[i], list))
      }
      const surplusData = this.deleteCorresponding(list, myPower)
      const fatherData = this.fatherHandle(allPower)
      // fatherData 权限type --- sonData 已有权限 --- surplusData 剩余权限 => 各自组合
      this.fromData = this.authorityRegular(surplusData, fatherData)
      this.toData = this.authorityRegular(sonData, fatherData)
      this.permissionSettingDialog = true
    },

    // 检出全部子权限
    detection(list) {
      const arr = []
      for (let i = 0; i < list.length; i++) {
        for (let k = 0; k < list[i].permissionList.length; k++) {
          arr.push(list[i].permissionList[k])
        }
      }
      return arr
    },

    // 查找对应子权限对象
    seekAuthority(id, list) {
      const itemData = list.find(item => item.reallyId === id)
      return itemData
    },

    // 全部删除id对应权限
    deleteCorresponding(allPower, myPower) {
      let list = allPower
      for (let i = 0; i < myPower.length; i++) {
        list = this.deleteSingleCorresponding(list, myPower[i])
      }
      return list
    },

    // 单个回归
    deleteSingleCorresponding(arr, id) {
      const list = arr.filter(item => item.reallyId !== id)
      return list
    },

    // 剥离权限
    fatherHandle(arr) {
      const list = arr.concat()
      for (let i = 0; i < list.length; i++) {
        list[i].permissionList = []
      }
      return list
    },

    // 父子规整(开始)
    authorityRegular(sonArr, fatherArr) {
      const parents = JSON.parse(JSON.stringify(this.duplicateRemoval(sonArr))) // 去重后对象(找父级)
      const fatherList = JSON.parse(JSON.stringify(this.seekParent(parents, fatherArr))) // 找父级
      // fatherList 对应父级
      const endData = this.aggregateData(sonArr, fatherList)
      return endData
    },

    // 去重
    duplicateRemoval(arr) {
      const list = arr.filter(item => item != undefined)
      const res = new Map()
      return list.filter((item) => !res.has(item.parentId) && res.set(item.parentId, 1))
    },

    // 找到对应父级
    seekParent(parents, fatherArr) {
      const list = []
      for (let i = 0; i < parents.length; i++) {
        for (let k = 0; k < fatherArr.length; k++) {
          if (fatherArr[k].reallyId === parents[i].parentId) {
            list.push(fatherArr[k])
          }
        }
      }
      return list
    },

    // 父子规整
    aggregateData(sonArr, fatherList) {
      for (let i = 0; i < fatherList.length; i++) {
        for (let k = 0; k < sonArr.length; k++) {
          if (sonArr[k]) {
            if (sonArr[k].parentId === fatherList[i].reallyId) {
              fatherList[i].permissionList.push(sonArr[k])
            }
          }
        }
      }
      return fatherList
    },

    // 完整权限树
    getCompletePermission(row) {
      completePermission().then(res => {
        const list = this.formatHandle(res.data)
        this.getPermissionIdListByRoleId(row, list)
      })
    },

    // 格式处理
    formatHandle(list) {
      const powerData = []
      // reallyId 原id
      for (let i = 0; i < list.length; i++) {
        const itemData = list[i]
        itemData.reallyId = list[i].id
        itemData.id = list[i].id
        // itemData.disabled = true
        itemData.parentId = 0
        if (list[i].permissionList && list[i].permissionList.length > 0) {
          const arr = list[i].permissionList
          const sonData = []
          for (let k = 0; k < arr.length; k++) {
            const sonItem = JSON.parse(JSON.stringify(arr[k]))

            sonItem.reallyId = arr[k].id
            sonItem.id = `${itemData.id}-${k + 1}`
            sonData.push(sonItem)
          }
          itemData.permissionList = sonData
        }

        powerData.push(itemData)
      }
      return powerData
    },

    // 监听穿梭框组件添加
    add(fromData, toData, obj) {
      function compare(property) {
        return function(a, b) {
          const value1 = a[property]
          const value2 = b[property]
          return value1 - value2
        }
      }
      const list = this.toData.sort(compare('id')).concat()
      this.toData = list
    },

    // 监听穿梭框组件移除
    remove(fromData, toData, obj) {
      function compare(property) {
        return function(a, b) {
          const value1 = a[property]
          const value2 = b[property]
          return value1 - value2
        }
      }
      const list = this.fromData.sort(compare('id')).concat()
      this.fromData = list
    },

    // 权限保存
    savePermissionSetting() {
      configPermission({
        roleId: this.role_Id,
        permissionList: this.regression(this.toData)
      }).then(res => {
        if (res.data.success) {
          this.$message.success('保存成功')
          this.permissionSettingDialog = false
        } else {
          this.$message.error(res.data.msg)
        }
      })
    },

    // 只要id
    regression(list) {
      const powerData = []
      for (let i = 0; i < list.length; i++) {
        if (list[i].permissionList && list[i].permissionList.length > 0) {
          const arr = list[i].permissionList
          for (let k = 0; k < arr.length; k++) {
            powerData.push(arr[k].reallyId)
          }
        }
      }
      return powerData
    }

  }

}
</script>
<style lang="scss" scoped>
$menuText: #14162E; // 侧边栏字体颜色
$hoverColor: #1D143C; // 鼠标停留主色调浅色
$mainColor: #3b425d; // 主色调

::v-deep .wl-transfer .transfer-main {
  height: calc(100% - 90px);
}

::v-deep .el-radio__label {
  display: none;
}

.span_cloum {
  &.active {
    color: #3b425d;
  }
}

.filter-container {
  width: 100%;
  height: 48px;
  line-height: 48px;

  .filter-item {
    display: inline-block;
    vertical-align: middle;
    margin-bottom: 10px;
  }

  .kInput {
    position: absolute;
    right: 20px;
  }

  .filter-title {
    height: 48px;
    line-height: 48px;
    font-size: 16px;
    font-weight: 500;
    margin-right: 22px;
    color: #14162E;
  }

  .user-item {
    margin-left: 10px;
    margin-right: 20px;
  }

  .room-type,
  .user-status,
  .account-status {
    margin-right: 20px;
  }
}

.top-btn {
  margin: 30px 0px 30px 0px;
  font-size: 14px;
  color: #ffffff;

  &:nth-of-type(2) {
    margin-left: 10px;
  }
}

.kSelect .el-select .el-input .el-input__inner {
  width: 124px;
}

::v-deep .el-select .el-input.is-focus .el-input__inner {
  border-color: $mainColor;
}

::v-deep .el-input__inner:focus {
  border-color: $mainColor;
}

.el-form-item__label-wrap .el-form-item__label {
  float: none;
}

.dialog_creatRoleDialog {
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin: 40px 180px;

  ::v-deep .el-select .el-select__tags>span {
    display: none;
  }

  .el-tag+.el-tag {
    margin-left: 10px;
  }

  .el-tag {
    color: $mainColor;
    background-color: #ffffff;
    border-color: $mainColor;

    ::v-deep .el-tag__close {
      color: $mainColor;
    }

    ::v-deep .el-icon-close:hover {
      color: #ffffff;
      background: $mainColor;
    }
  }
}

::v-deep .el-switch__label.is-active {
  color: $mainColor;
}

.dialog_permission {
  display: flex;
  flex-direction: row;
  justify-content: center;
  margin: 10px;
  width: 800px;
}
</style>
